package com.ruoyi.electronicFence.service.Impl;

import java.time.*;
import java.util.*;
import java.util.stream.Collectors;

import com.ruoyi.common.GenericMethods;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.electronicFence.domain.*;
import com.ruoyi.electronicFence.domain.TEfEquipmentDeviceVo;
import com.ruoyi.electronicFence.domain.TEfEquipmentStatusVo;
import com.ruoyi.electronicFence.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.electronicFence.service.ITEfEquipmentDeviceService;

/**
 * 设备或场景与监测设备关联  Service业务层处理
 *
 * @author sxygsj
 * @date 2024-05-29
 */
@Service
public class TEfEquipmentDeviceServiceImpl implements ITEfEquipmentDeviceService
{
    @Autowired
    private TEfEquipmentDeviceMapper tEfEquipmentDeviceMapper;


    @Autowired
    private TEfAlarmMapper tEfAlarmMapper;

    @Autowired
    private TDeviceStatusMapper tDeviceStatusMapper;

    @Autowired
    private TEquipmentMonitorDeviceMapper tEquipmentMonitorDeviceMapper;

    @Autowired
    private TEfHistoryEquipmentStatusMapper tEfHistoryEquipmentStatusMapper;

    /**
     * 查询设备或场景与监测设备关联
     *
     * @param id 设备或场景与监测设备关联  主键
     * @return 设备或场景与监测设备关联
     */
    @Override
    public TEfEquipmentDevice selectTEfEquipmentDeviceById(Long id)
    {
            TEfEquipmentDevice tEfEquipmentDevice = tEfEquipmentDeviceMapper.selectTEfEquipmentDeviceById(id);

            TEfEquipmentDevice tEfEquipmentDevice1 = new TEfEquipmentDevice();
            tEfEquipmentDevice1.setDeviceId(tEfEquipmentDevice.getDeviceId());
            List<TDeviceStatus> tDeviceStatuses = tEfEquipmentDeviceMapper.selectTEfEquipmentDeviceDetailsListV2(tEfEquipmentDevice1);
            tEfEquipmentDevice.settDeviceStatusList(tDeviceStatuses);

        return tEfEquipmentDevice;
    }

    @Override
    public TEfEquipmentDevice selectTEfEquipmentDeviceDetailsListById(Long id) {
        return tEfEquipmentDeviceMapper.selectTEfEquipmentDeviceDetailsListById(id);
    }

    @Override
    public TEfEquipmentDevice selectTEfEquipmentDeviceByDeviceId(String deviceId) {
        return tEfEquipmentDeviceMapper.selectTEfEquipmentDeviceByDeviceId(deviceId);
    }

    /**
     * 查询设备或场景与监测设备关联  列表
     *
     * @param tEfEquipmentDevice 设备或场景与监测设备关联
     * @return 设备或场景与监测设备关联
     */
    @Override
    public List<TEfEquipmentDevice> selectTEfEquipmentDeviceList(TEfEquipmentDevice tEfEquipmentDevice)
    {
        return tEfEquipmentDeviceMapper.selectTEfEquipmentDeviceList(tEfEquipmentDevice);
    }


    /**
     * 查询设备或场景与监测设备关联  列表
     *
     * @param tEfEquipmentDevice 设备或场景与监测设备关联
     * @return 设备或场景与监测设备关联
     */
    @Override
    public List<TEfEquipmentDeviceVo> selectTEfEquipmentDeviceDetailsList(TEfEquipmentDevice tEfEquipmentDevice)
    {
        return tEfEquipmentDeviceMapper.selectTEfEquipmentDeviceDetailsList(tEfEquipmentDevice);
    }

    /**
     * 查询设备或场景与监测设备关联  列表
     *
     * @param tEfEquipmentDevice 设备或场景与监测设备关联
     * @return 设备或场景与监测设备关联
     */
    @Override
    public List<TEfEquipmentDeviceVo> selectTEfEquipmentDeviceDetailsListV2(TEfEquipmentDevice tEfEquipmentDevice)
    {

        List<TEfEquipmentDeviceVo> tEfEquipmentDeviceVos = tEfEquipmentDeviceMapper.selectTEfEquipmentDeviceDetailsList(tEfEquipmentDevice);
        for (TEfEquipmentDeviceVo data: tEfEquipmentDeviceVos){
            TEfEquipmentDevice tEfEquipmentDevice1 = new TEfEquipmentDevice();
            tEfEquipmentDevice1.setDeviceId(data.getDeviceId());
            List<TDeviceStatus> tDeviceStatuses = tEfEquipmentDeviceMapper.selectTEfEquipmentDeviceDetailsListV2(tEfEquipmentDevice1);
            data.setTDeviceStatusList(tDeviceStatuses);
        }
        return tEfEquipmentDeviceVos;
    }
    /**
     * 新增设备或场景与监测设备关联
     *
     * @param tEfEquipmentDevice 设备或场景与监测设备关联
     * @return 结果
     */
    @Override
    public int insertTEfEquipmentDevice(TEfEquipmentDevice tEfEquipmentDevice)
    {

        return tEfEquipmentDeviceMapper.insertTEfEquipmentDevice(tEfEquipmentDevice);

    }

    /**
     * 新增设备或场景与监测设备关联
     *
     * @param tEfEquipmentDevice 设备或场景与监测设备关联
     * @return 结果
     */
    @Override
    public AjaxResult insertEquipmentMonitorDevice(TEfEquipmentDevice tEfEquipmentDevice)

    {
        AjaxResult ajaxResult = new AjaxResult();
        try {
            if (tEfEquipmentDevice == null) {
                throw new IllegalArgumentException("tEfEquipmentDevice 参数不能为空");
            }

            // 生成设备ID
            UUID uuid = UUID.randomUUID();
            String deviceId = uuid.toString();

            // 设置设备ID
            tEfEquipmentDevice.setDeviceId(deviceId);
            int i=0;
            // 插入到 tEfEquipmentDeviceMapper
             i = tEfEquipmentDeviceMapper.insertTEfEquipmentDevice(tEfEquipmentDevice);
            int rowsInserted=0;
            // 插入设备到监控表
            if (tEfEquipmentDevice.gettDeviceStatusList()!=null){
                rowsInserted = tEfEquipmentDeviceMapper.insertEquipmentMonitorDevice(tEfEquipmentDevice);
            }
            ArrayList<HashMap<String, Object>> arrayList = new ArrayList<>();
            HashMap<String, Object> map = new HashMap<>();
            HashMap<String, Object> map2 = new HashMap<>();
            map.put("tableName","t_ef_equipment_device");
            map.put("rows",i);
            map2.put("tableName","t_equipment_monitor_device");
            map2.put("rows",rowsInserted);
            arrayList.add(map);
            arrayList.add(map2);
            ajaxResult.isSuccess();
            ajaxResult.put("code",200);
            ajaxResult.put("msg","新增成功");
            ajaxResult.put("data",arrayList);

            // 返回结果
            return ajaxResult;

        } catch (IllegalArgumentException e) {
            // 参数异常处理
            System.err.println("参数异常: " + e.getMessage());
            // 可以选择抛出或者返回错误信息
            ajaxResult.isError();
            ajaxResult.put("code",200);
            ajaxResult.put("msg","参数异常"+ e.getMessage());
            ajaxResult.put("data",null);
            return ajaxResult;
        } catch (Exception e)

        {
            // 其他异常处理
            System.err.println("插入设备时发生异常: " + e.getMessage());
            ajaxResult.isError();
            ajaxResult.put("code",200);
            ajaxResult.put("msg","插入设备时发生异常: " + e.getMessage());
            ajaxResult.put("data",null);
            return ajaxResult;

        }
    }

    /**
     * 修改设备或场景与监测设备关联
     *
     * @param tEfEquipmentDevice 设备或场景与监测设备关联
     * @return 结果
     */
    @Override
    public int updateTEfEquipmentDevice(TEfEquipmentDevice tEfEquipmentDevice)
    {
        return tEfEquipmentDeviceMapper.updateTEfEquipmentDevice(tEfEquipmentDevice);
    }

    /**
     * 修改设备或场景与监测设备关联
     *
     * @param tEfEquipmentDevice 设备或场景与监测设备关联
     * @return 结果
     */
    @Override
//    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateTEfEquipmentDeviceV2(TEfEquipmentDevice tEfEquipmentDevice)
    {
        tEfEquipmentDeviceMapper.deleteTEfEquipmentDeviceById(tEfEquipmentDevice.getId());
        AjaxResult ajaxResult = new AjaxResult();
        try {
            if (tEfEquipmentDevice == null) {
                throw new IllegalArgumentException("tEfEquipmentDevice 参数不能为空");
            }

            // 生成设备ID
            UUID uuid = UUID.randomUUID();
            String deviceId = uuid.toString();

            // 设置设备ID
            tEfEquipmentDevice.setDeviceId(deviceId);
            int i=0;
            // 插入到 tEfEquipmentDeviceMapper
//            tEfEquipmentDevice.setId();
            i = tEfEquipmentDeviceMapper.insertTEfEquipmentDevice(tEfEquipmentDevice);
            int rowsInserted=0;
            // 插入设备到监控表
            if (tEfEquipmentDevice.gettDeviceStatusList()!=null){
                rowsInserted = tEfEquipmentDeviceMapper.insertEquipmentMonitorDevice(tEfEquipmentDevice);
            }
            ArrayList<HashMap<String, Object>> arrayList = new ArrayList<>();
            HashMap<String, Object> map = new HashMap<>();
            HashMap<String, Object> map2 = new HashMap<>();
            map.put("tableName","t_ef_equipment_device");
            map.put("rows",i);
            map2.put("tableName","t_equipment_monitor_device");
            map2.put("rows",rowsInserted);
            arrayList.add(map);
            arrayList.add(map2);
            ajaxResult.isSuccess();
            ajaxResult.put("code",200);
            ajaxResult.put("msg","修改成功");
            ajaxResult.put("data",arrayList);

            // 返回结果
            return ajaxResult;

        } catch (IllegalArgumentException e) {
            // 参数异常处理
            System.err.println("参数异常: " + e.getMessage());
            // 可以选择抛出或者返回错误信息
            ajaxResult.isError();
            ajaxResult.put("code",200);
            ajaxResult.put("msg","参数异常"+ e.getMessage());
            ajaxResult.put("data",null);
            return ajaxResult;
        } catch (Exception e) {
            // 其他异常处理
            System.err.println("插入设备时发生异常: " + e.getMessage());
            ajaxResult.isError();
            ajaxResult.put("code",200);
            ajaxResult.put("msg","插入设备时发生异常: " + e.getMessage());
            ajaxResult.put("data",null);
            return ajaxResult;

        }
    }
    @Override
    public AjaxResult updateTEfEquipmentDeviceV3(TEfEquipmentDevice tEfEquipmentDevice)
    {
        AjaxResult ajaxResult = new AjaxResult();
        List<TDeviceStatus> tDeviceStatuses = tEfEquipmentDevice.gettDeviceStatusList();
        int row=0;
        int row2=0;
        String deviceId = tEfEquipmentDevice.getDeviceId();
        //删除关联
        TEquipmentMonitorDevice tEquipmentMonitorDevice = new TEquipmentMonitorDevice();
        tEquipmentMonitorDevice.setEquipmentId(deviceId);
        tEquipmentMonitorDeviceMapper.deleteTEquipmentMonitorDevice(tEquipmentMonitorDevice);
        //批量新增关联
        for (TDeviceStatus device: tDeviceStatuses){
            TEquipmentMonitorDevice insert = new TEquipmentMonitorDevice();
            insert.setEquipmentId(deviceId);
            insert.setMonitorDeviceId(device.getDeviceId());
            row = tEquipmentMonitorDeviceMapper.insertTEquipmentMonitorDevice(insert);
        }
         row2 = tEfEquipmentDeviceMapper.updateTEfEquipmentDevice(tEfEquipmentDevice);

        if (row>0 || row2>0){
            ajaxResult.put("msg","修改成功");
            ajaxResult.put("code",200);

        }else {
            ajaxResult.put("msg","修改失败");
            ajaxResult.put("code",500);
        }
        return ajaxResult;
    }


    /**
     * 批量删除设备或场景与监测设备关联
     *
     * @param ids 需要删除的设备或场景与监测设备关联  主键
     * @return 结果
     */
    @Override
    public int deleteTEfEquipmentDeviceByIds(Long[] ids)
    {
        return tEfEquipmentDeviceMapper.deleteTEfEquipmentDeviceByIds(ids);
    }

    /**
     * 删除设备或场景与监测设备关联  信息
     *
     * @param id 设备或场景与监测设备关联  主键
     * @return 结果
     */
    @Override
    public int deleteTEfEquipmentDeviceById(Long id)
    {
        return tEfEquipmentDeviceMapper.deleteTEfEquipmentDeviceById(id);
    }

    @Override
    public List<TEfEquipmentStatusVo> getEquipmentStatus() {

        TEfEquipmentDevice tEfEquipmentDevice = new TEfEquipmentDevice();
        ArrayList<TEfEquipmentStatusVo> TEfEquipmentStatusVos = new ArrayList<>();
        List<TEfEquipmentDevice> tEfEquipmentDevices = tEfEquipmentDeviceMapper.selectTEfEquipmentDeviceList(tEfEquipmentDevice);

        for (TEfEquipmentDevice tEfEquipmentDevice1:tEfEquipmentDevices){
            TEfEquipmentStatusVo tEfEquipmentStatusVo = new TEfEquipmentStatusVo();
            LocalDateTime endTime = LocalDateTime.now();
            LocalDateTime startTime = endTime.minusMinutes(5);

            TEfAlarm tEfAlarm = new TEfAlarm();
            tEfAlarm.setStartTime(startTime);
            tEfAlarm.setStartTime(endTime);
            tEfAlarm.setMonitorDeviceId(tEfEquipmentDevice1.getDeviceId());
            List<TEfAlarm> list = tEfAlarmMapper.selectTEfAlarmList(tEfAlarm);
            if (list.size()>0){
                TEfAlarm tEfAlarm1 = list.get(list.size()-1);
                tEfEquipmentStatusVo.setEquipmentStatus("异常");
                tEfEquipmentStatusVo.setAlarmTime(tEfAlarm1.getAlarmTime());

            }else {
                tEfEquipmentStatusVo.setEquipmentStatus("正常");
            }
            tEfEquipmentStatusVo.setEquipmentName(tEfEquipmentDevice1.getEquipmentName());
            tEfEquipmentStatusVo.setAreaName(tEfEquipmentDevice1.getAreaName());
            TEfEquipmentStatusVos.add(tEfEquipmentStatusVo);
        }
        return TEfEquipmentStatusVos;
    }

    @Override
    public List<TEfEquipmentDevice> getEquipmentStatus2() {

        TEfEquipmentDevice tEfEquipmentDevice = new TEfEquipmentDevice();
        List<TEfEquipmentDevice> tEfEquipmentDevices = tEfEquipmentDeviceMapper.selectTEfEquipmentDeviceList(tEfEquipmentDevice);
        for (TEfEquipmentDevice equipmentDevice :tEfEquipmentDevices){
            Integer durationSeconds = equipmentDevice.getDurationSeconds();
            String s = GenericMethods.formatDuration(durationSeconds);
            equipmentDevice.setDurationSecondsStr(s);
            String equipmentStatus = equipmentDevice.getEquipmentStatus();
            switch (equipmentStatus) {
                case "0":
                    equipmentDevice.setEquipmentStatus("正常");
                    break;
                case "1":
                    equipmentDevice.setEquipmentStatus("预警");
                    break;
                case "2":
                    equipmentDevice.setEquipmentStatus("断电");
                    break;

            }
            LocalDateTime dataTime = equipmentDevice.getDataTime();

            if (dataTime!=null){
                // 将LocalDateTime转换为ZonedDateTime
                ZonedDateTime zonedDateTime = dataTime.atZone(ZoneOffset.UTC);
                // 从ZonedDateTime中提取Instant，并减去秒数
                Instant instant = zonedDateTime.toInstant().minusSeconds(durationSeconds);
                // 将结果转换回LocalDateTime
                LocalDateTime resultDateTime = instant.atZone(ZoneOffset.UTC).toLocalDateTime();
                equipmentDevice.setStatusStartDateTime(resultDateTime);
            }

        }

        return tEfEquipmentDevices;
    }
    /**
     * 获取所有设备的状态信息，并根据最近的历史记录更新其在线/离线状态。
     *
     * 此方法首先获取所有设备的基础信息，然后通过查询每个设备的最新历史状态记录，
     * 判断设备是否在最近5分钟内有活动。如果有，则更新设备状态；如果没有，则标记为离线。
     *
     * @return 返回设备列表，每个设备带有最新的状态信息。
     */
    @Override
    public List<TEfEquipmentDeviceVo> getEquipmentStatusV3(TEfEquipmentDevice tEfEquipmentDevice) {

        List<TEfEquipmentDeviceVo> tEfEquipmentDevices = tEfEquipmentDeviceMapper.selectTEfEquipmentDeviceDetailsList(tEfEquipmentDevice);

        // 获取当前时间点
        LocalDateTime now = LocalDateTime.now();

        // 遍历设备列表
        for (TEfEquipmentDeviceVo equipmentDevice : tEfEquipmentDevices) {
            // 创建一个历史状态查询对象
            TEfHistoryEquipmentStatus query = new TEfHistoryEquipmentStatus();

            // 设置查询条件为当前设备ID
            query.setDeviceId(equipmentDevice.getDeviceId());

            // 查询该设备最新的历史状态记录
            TEfHistoryEquipmentStatus tEfHistoryEquipmentStatus = tEfHistoryEquipmentStatusMapper.selectTEfHistoryEquipmentStatusLast(query);

            if (tEfHistoryEquipmentStatus != null) {
                // 获取历史记录中的最后状态结束时间
                LocalDateTime statusEndDatetime = tEfHistoryEquipmentStatus.getStatusEndDatetime();

                // 计算当前时间和状态结束时间之间的差值
                Duration between = Duration.between(statusEndDatetime, now);
                int seconds = (int) between.getSeconds();

                // 判断是否在5分钟内有历史记录
                if (seconds < 600) {
                    // 更新设备状态信息
                    equipmentDevice.setEquipmentStatus(tEfHistoryEquipmentStatus.getEquipmentStatus());
                    equipmentDevice.setDurationSecondsStr(tEfHistoryEquipmentStatus.getDurationSecondsStr());
                    equipmentDevice.setStatusStartDateTime(tEfHistoryEquipmentStatus.getStatusStartDatetime());
                } else {
                    // 超过5分钟未收到状态更新，标记为离线
                    equipmentDevice.setEquipmentStatus("离线");
                }
            } else {
                // 若没有历史记录，直接标记为离线
                equipmentDevice.setEquipmentStatus("离线");
            }
        }
//
        // 这是你过滤后的列表
        if (tEfEquipmentDevices.size()>0 && tEfEquipmentDevice!=null){
            String equipmentStatus = tEfEquipmentDevice.getEquipmentStatus();
            if (equipmentStatus!=null){
                List<TEfEquipmentDeviceVo> filteredDevices = tEfEquipmentDevices.stream()
                        .filter(device -> tEfEquipmentDevice.getEquipmentStatus().equals(device.getEquipmentStatus()))
                        .collect(Collectors.toList());

                // 排序（不进行过滤）
                List<TEfEquipmentDeviceVo> sortedDevices = filteredDevices.stream()
                        .sorted(Comparator.comparing(TEfEquipmentDeviceVo::getEquipmentStatus))  // 按照设备状态排序（升序）
                        .collect(Collectors.toList());
                tEfEquipmentDevices = sortedDevices;
            }


        }

        //有一个列表 tEfEquipmentDevices 按照EquipmentStatus排序 正常 停机 离线
//        tEfEquipmentDevices
        // 返回更新后的设备列表

        for (TEfEquipmentDeviceVo data: tEfEquipmentDevices){
            TEfEquipmentDevice tEfEquipmentDevice1 = new TEfEquipmentDevice();
            tEfEquipmentDevice1.setDeviceId(data.getDeviceId());
            List<TDeviceStatus> tDeviceStatuses = tEfEquipmentDeviceMapper.selectTEfEquipmentDeviceDetailsListV2(tEfEquipmentDevice1);
            data.setTDeviceStatusList(tDeviceStatuses);
        }

        // 定义状态的优先级
        final int NORMAL = 1;
        final int ALARM  = 2;
        final int STOPPED = 3;
        final int OFFLINE = 4;

        // 使用 Comparator 进行排序
        Collections.sort(tEfEquipmentDevices, new Comparator<TEfEquipmentDeviceVo>() {
            @Override
            public int compare(TEfEquipmentDeviceVo d1, TEfEquipmentDeviceVo d2) {
                int status1 = getStatusValue(d1.getEquipmentStatus());
                int status2 = getStatusValue(d2.getEquipmentStatus());
                return Integer.compare(status1, status2);
            }

            private int getStatusValue(String status) {
                switch (status) {
                    case "正常":
                        return NORMAL;
                    case "预警":
                        return ALARM;
                    case "停机":
                        return STOPPED;
                    case "离线":
                        return OFFLINE;
                    default:
                        throw new IllegalArgumentException("未知的状态: " + status);
                }
            }
        });

        return tEfEquipmentDevices;
    }

    @Override
    public int updateHistoryTEfEquipmentStatus(TEfEquipmentDevice tEfEquipmentDevice) {
        return 0;
    }

//
}
